package cn.tedu.charging.cost.service;

import cn.tedu.charging.common.pojo.param.ProgressCostParam;
import cn.tedu.charging.common.pojo.po.ChargingCostRulePO;
import cn.tedu.charging.common.pojo.vo.ProgressCostVO;
import cn.tedu.charging.cost.dao.repository.CostRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Service
@Slf4j
public class CostService {
    // @Autowired
    // private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private CostRepository costRepository;

    public ProgressCostVO calculate(ProgressCostParam param) {
        // 1.查询当前时间点，当前设备对应的尖峰平谷，具体计价方案powerFee
        ChargingCostRulePO costRule = getCostRule(param.getStationId(), LocalDateTime.now().getHour());
        log.debug("当前订单计价规则{}", costRule);
        // 2.计算单次金额
        BigDecimal cost = caculateCost(param, costRule);
        // 3.使用redis客户端执行inCrBy，做缓存数据累加存储
        BigDecimal totalCost = accumulateCost(param.getOrderNo(), cost);
        ProgressCostVO vo = new ProgressCostVO();
        vo.setTotalCost(totalCost.doubleValue());
        vo.setPowerFee(costRule.getPowerFee().doubleValue());
        return vo;
    }

    private BigDecimal accumulateCost(String orderNo, BigDecimal cost) {
        String orderKey= "charging:order:total:"+orderNo;
        Double increment = stringRedisTemplate.opsForValue().increment(orderKey, cost.doubleValue());
        log.debug("本次累加金额:{}", increment);
        return new BigDecimal(increment);
    }

    private BigDecimal caculateCost(ProgressCostParam param, ChargingCostRulePO costRule) {
        // 校验 param 是否为空
        if (param == null || param.getChargingCapacity() == null) {
            throw new IllegalArgumentException("参数 ProgressCostParam 或其属性 chargingCapacity 不能为空");
        }

        // 校验 costRule 是否为空
        if (costRule == null || costRule.getPowerFee() == null) {
            throw new IllegalArgumentException("未找到对应的充电费用规则或电价为空");
        }

        // 计算充电费用
        BigDecimal chargingCapacity = new BigDecimal(param.getChargingCapacity());
        BigDecimal powerFee = costRule.getPowerFee();
        BigDecimal cost = powerFee.multiply(chargingCapacity).setScale(
                2, BigDecimal.ROUND_HALF_UP);
        return cost;
    }

    private ChargingCostRulePO getCostRule(Integer stationId, int hour) {
        ChargingCostRulePO costRule = costRepository.getCostRule(stationId, hour);
        if (costRule == null) {
            log.warn("未找到站点 {} 在 {} 小时的费用规则", stationId, hour);
            // 可以选择抛出异常或返回默认值
            throw new IllegalStateException("未找到对应的充电费用规则");
        }
        return costRule;
    }
}
